//<<<+++OPENSOURCE
//<<<+++OPENSOURCE_LICENSE
/**
 * @addtogroup FPDFAPI
 * @{
 */

/**
 * @file
 * @brief Platform dependant support for Windows.
 */
//<<<+++OPENSOURCE_MUST_BEGIN
#ifndef _FX_GE_WIN32_H_
#define _FX_GE_WIN32_H_

#ifdef _WIN32

#ifndef _WINDOWS_
#include <windows.h>
#endif
//<<<+++OPENSOURCE_MUST_END

/** @brief This is a memory-based stream. */
#define WINDIB_OPEN_MEMORY    0x1
/** @brief Create a new input stream from a path name.*/
#define WINDIB_OPEN_PATHNAME  0x2

/** @brief A structure used to indicate how to open a new image file or stream. */
typedef struct  WINDIB_Open_Args_
{
	/**A set of bit flags indicating how to use the structure.*/
    int         flags;
    /** The first byte of the file in memory.*/
    const FX_BYTE*  memory_base;
	/** The size in bytes of the file in memory.*/
    size_t    memory_size;
    /** A pointer to an 16-bit file pathname. */
    FX_LPCWSTR  path_name;	
} WINDIB_Open_Args_;

/** @brief DIB Support in Windows OS. */
class CFX_WindowsDIB : public CFX_DIBitmap
{
public:
	/**
	 * Get Windows bitmap info structure.
	 * The result is a binary string that can be used at a BITMAPINFO structure.
	 *
	 * @param[in] pBitmap		The input DIB bitmap.
	 * @return The windows bitmap info structure for the DIB.
	 */
	static CFX_ByteString	GetBitmapInfo(const CFX_DIBitmap* pBitmap);

	/**
	 * Construct a bitmap from existing data.
	 *
	 * @param[in] pbmi			The windows bitmap info structure.
	 * @param[in] pData			The bitmap data.
	 * @return A DIB.
	 */
	static CFX_DIBitmap* LoadFromBuf(BITMAPINFO* pbmi, void* pData);

	/**
	 * Convert to device compatible bitmap.
	 *
	 * @param[in] pBitmap		The input DIB.
	 * @param[in] hDC			The input DC.
	 * @return A device dependent bitmap compatible with the input DC.
	 */
	static HBITMAP		GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC);

	/**
	 * Load DI bitmap from DDB.
	 * If hDC is NULL, system display DC will be used.
	 *
	 * @param[in] hDC			The input DC.
	 * @param[in] hBitmap		The input device dependent bitmap.
	 * @param[in] pPalette		The bmp's palette, applicable to 1bppRgb and 8bppRgb formats.
	 * @param[in] size		    The palette's size.
	 * @return A DIB.
	 */
	static CFX_DIBitmap* LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette = NULL, FX_DWORD size = 256);

	/**
	* Load DI bitmap from file. Unicode version.
	* Without GDI+ support, we supports only BMP file.
	* With GDI support, we support much more.
	*
	* @param[in] filename		The input full file path.
	* @return A DIB.
	*/
	static CFX_DIBitmap* LoadFromFile(FX_LPCWSTR filename);
	/**
	* Load DI bitmap from file. Local version.
	* Without GDI+ support, we supports only BMP file.
	* With GDI support, we support much more.
	*
	* @param[in] filename		The input full file path.
	* @return A DIB.
	*/
	static CFX_DIBitmap* LoadFromFile(FX_LPCSTR filename) { return LoadFromFile(CFX_WideString::FromLocal(filename)); }


    /**
	 * Load DI bitmap from file. Unicode version.
	 * Without GDI+ support, we supports only BMP file.
	 * With GDI support, we support much more.
	 *
	 * @param[in] args		The input full file path or memory.
	 * @return A DIB.
	 */

	static CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args);
	/**
	 * Construct a DIB that can be efficiently interact with Windows device.
	 * Currently the constructed DIB will always in FXDIB_Rgb format.
	 *
	 * @param[in] hDC			The input windows device context.
	 * @param[in] width			The bimtap width.
	 * @param[in] height		The bitmap height.
	 */
	CFX_WindowsDIB(HDC hDC, int width, int height);

	/** The destructor. */
	~CFX_WindowsDIB();

	/** Get the DC. */
	HDC					GetDC() const { return m_hMemDC; }
	/** Get the bitmap. */
	HBITMAP				GetWindowsBitmap() const { return m_hBitmap; }

	/**
	 * Load from a device.
	 *
	 * @param[in] hDC			The input windows device context.
	 * @param[in] left			The x-coordinate in the windows DC.
	 * @param[in] top			The y-coordinate in the windows DC.
	 */
	void				LoadFromDevice(HDC hDC, int left, int top);

	/**
	 * Output to a device.
	 *
	 * @param[out] hDC			The output windows device.
	 * @param[in] left			The x-coordinate in the windows DC.
	 * @param[in] top			The y-coordinate in the windows DC.
	 */
	void				SetToDevice(HDC hDC, int left, int top);

protected:
	/** The memory DC. */
	HDC					m_hMemDC;
	/** The current bitmap. */
	HBITMAP				m_hBitmap;
	/** The old bitmap. */
	HBITMAP				m_hOldBitmap;
};

/** @brief PDF windows device class. */
class CFX_WindowsDevice : public CFX_RenderDevice
{
public:
	static IFX_RenderDeviceDriver*	CreateDriver(HDC hDC, FX_BOOL bCmykOutput = FALSE);

	/**
	 * Construct with a DC.
	 *
	 * @param[in] hDC		The input windows DC.
	 * @param[in] bCmykOutput	Output Cmyk color instruction directly.(Only effected in ps printer now)
	 */
	CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput = FALSE, FX_BOOL bForcePSOutput = FALSE, int psLevel = 2);

	/** Get the DC. */
	HDC		GetDC() const;

	/** Whether the user thinks this is a PS printer. */
	FX_BOOL m_bForcePSOutput;

	/** The level of ps printer.*/
	static int m_psLevel;
};

//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
/** @brief PCL printer device class. */
class CFX_PCLDevice : public CFX_RenderDevice
{
public:
	static IFX_RenderDeviceDriver*	CreateDriver(HDC hDC, int pcl_level, FX_BOOL bColor, FX_LPCSTR DriverName = NULL);

	/**
	 * Construct with a DC.
	 *
	 * @param[in] hDC		The input windows DC.
	 * @param[in] bColor	Whether this is a chromatic printer.
	 */
	CFX_PCLDevice(HDC hDC, int pcl_level, FX_BOOL bColor, FX_LPCSTR DriverName = NULL);

	virtual void Begin() { m_pDeviceDriver->Begin(); }
	virtual void End() { m_pDeviceDriver->End(); }
};
//<<<+++OPENSOURCE_END

#if _FX_OS_ == _FX_WIN32_MOBILE_
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class CFX_WinGlyphProvider : public IFX_GlyphProvider
{
protected:
	virtual FX_LPVOID	MapFont(const CFX_ByteString& name, FX_BOOL bTrueType, FX_DWORD flags, 
							int font_weight, int WindowPC, CFX_SubstFont* pSubstFont);

	virtual FX_RECT		GetGlyphBBox(FX_LPVOID font_handle, FX_WCHAR unicode,
							class CFX_Font* pFont,	FX_DWORD charcode);

	virtual FX_BOOL		GetGlyphBitmap(FX_LPVOID font_handle, FX_WCHAR unicode, class CFX_Font* pFont,
							FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, BitmapType &type,
							int& left, int& top, int& pixel_width, int& pixel_height, 
							FX_LPBYTE& buffer, int& stride);
};
//<<<+++OPENSOURCE_END
#endif		// _FX_OS_ == _FX_WIN32_MOBILE_

#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
/** @brief Windows bitmap device. For Windows CE, we should use CFX_FxgeDevice, instead of this one. */
class CFX_WinBitmapDevice : public CFX_RenderDevice
{
public:
	/**
	 * Construct with bitmap size and format.
	 *
	 * @param[in] width			The bitmap width.
	 * @param[in] height		The bitmap height.
	 * @param[in] format		The bitmap format.
	 */
	CFX_WinBitmapDevice(int width, int height, FXDIB_Format format);
	/** The destructor. */
	~CFX_WinBitmapDevice();

	/** Get the DC. */
	HDC		GetDC() { return m_hDC; }

protected:
	/** The current bitmap. */
	HBITMAP	m_hBitmap;
	/** The old bitmap. */
	HBITMAP m_hOldBitmap;
	/** The DC. */
	HDC		m_hDC;
};
#endif		// _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_

//<<<+++OPENSOURCE_MUST_BEGIN
#endif		// _WIN32
//<<<+++OPENSOURCE_MUST_END

//<<<+++OPENSOURCE_MUST_BEGIN
#endif		// _FX_GE_WIN32_H_
//<<<+++OPENSOURCE_MUST_END
/** @} */
